+++ /dev/null
-# Copyright (C) 2011 Colin Walters <walters@verbum.org>
-#
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2 of the License, or (at your option) any later version.
-#
-# This library is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# Lesser General Public License for more details.
-#
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the
-# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-# Boston, MA 02111-1307, USA.
-
-bin_SCRIPTS += src/osbuild/ostree-buildone \
- src/osbuild/ostree-buildone-make \
- src/osbuild/ostree-buildone-makeinstall-split-artifacts \
- $(NULL)
--- /dev/null
+# Copyright (C) 2011 Colin Walters <walters@verbum.org>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+bin_SCRIPTS += src/ostbuild/ostbuild-one \
+ src/ostbuild/ostbuild-one-make \
+ src/ostbuild/ostbuild-one-makeinstall-split-artifacts \
+ $(NULL)
include Makefile-otutil.am
include Makefile-libostree.am
include Makefile-ostree.am
-include Makefile-osbuild.am
+include Makefile-ostbuild.am
include Makefile-triggers.am
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2011 Colin Walters <walters@verbum.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Colin Walters <walters@verbum.org>
- */
-
-#include "config.h"
-
-#include <gio/gio.h>
-
-#include <string.h>
-
-#include "ob-builtins.h"
-
-static OsbuildBuiltin builtins[] = {
- { "buildone", osbuild_builtin_buildone, 0 },
- { NULL }
-};
-
-static int
-usage (char **argv, gboolean is_error)
-{
- OsbuildBuiltin *builtin = builtins;
- void (*print_func) (const gchar *format, ...);
-
- if (is_error)
- print_func = g_printerr;
- else
- print_func = g_print;
-
- print_func ("usage: %s COMMAND [options]\n",
- argv[0]);
- print_func ("Builtin commands:\n");
-
- while (builtin->name)
- {
- print_func (" %s\n", builtin->name);
- builtin++;
- }
- return (is_error ? 1 : 0);
-}
-
-
-int
-main (int argc,
- char **argv)
-{
- OsbuildBuiltin *builtin;
- const char *cmd;
-
- g_type_init ();
-
- g_set_prgname (argv[0]);
-
- builtin = builtins;
-
- if (argc < 2)
- return usage (argv, 1);
-
- cmd = argv[1];
-
- while (builtin->name)
- {
- GError *error = NULL;
- if (strcmp (cmd, builtin->name) == 0)
- {
- int i;
- int tmp_argc;
- char **tmp_argv;
-
- tmp_argc = argc - 1;
- tmp_argv = g_new0 (char *, tmp_argc + 1);
-
- tmp_argv[0] = (char*)builtin->name;
- for (i = 0; i < tmp_argc; i++)
- tmp_argv[i+1] = argv[i+2];
- if (!builtin->fn (tmp_argc, tmp_argv, NULL, &error))
- {
- g_free (tmp_argv);
- g_printerr ("%s\n", error->message);
- g_clear_error (&error);
- return 1;
- }
- g_free (tmp_argv);
- return 0;
- }
- builtin++;
- }
-
- g_printerr ("Unknown command '%s'\n", cmd);
- return usage (argv, 1);
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2011 Colin Walters <walters@verbum.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Colin Walters <walters@verbum.org>
- */
-
-#include "config.h"
-
-#include "otutil.h"
-#include "ob-builtins.h"
-
-#include <glib/gi18n.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-
-static char *repo_path;
-static char *ref;
-static char *name;
-static char *generator;
-static char *resultdir;
-static gboolean raw;
-
-static GOptionEntry options[] = {
- { "repo", 0, 0, G_OPTION_ARG_FILENAME, &repo_path, "Repository path", "repo" },
- { "rev", 'r', 0, G_OPTION_ARG_STRING, &ref, "Build using this tree", "rev" },
- { "name", 0, 0, G_OPTION_ARG_STRING, &name, "Name of the source", "source" },
- { "generator", 0, 0, G_OPTION_ARG_FILENAME, &generator, "Script to run on installed tree", "script" },
- { "raw", 0, 0, G_OPTION_ARG_NONE, &raw, "Do not instantiate a tree, use current", NULL },
- { "resultdir", 0, 0, G_OPTION_ARG_FILENAME, &resultdir, "Directory for output artifacts", "dir" },
- { NULL }
-};
-
-static char *
-get_tmpdir (void) G_GNUC_UNUSED;
-
-static char *
-get_tmpdir (void)
-{
- char *tmp_prefix = g_strdup (g_getenv ("XDG_RUNTIME_DIR"));
- char *ret;
-
- if (tmp_prefix)
- {
- ret = g_strdup_printf ("%s/osbuild", tmp_prefix);
- }
- else
- {
- tmp_prefix = g_strdup_printf ("/tmp/osbuild-%d", getuid ());
- if (!g_file_test (tmp_prefix, G_FILE_TEST_IS_DIR))
- {
- if (!mkdir (tmp_prefix, 0755))
- {
- g_printerr ("Failed to make logging directory %s\n", tmp_prefix);
- exit (1);
- }
- }
- ret = tmp_prefix;
- tmp_prefix = NULL;
- }
- g_free (tmp_prefix);
- return ret;
-}
-
-static gboolean
-open_log (const char *name,
- GOutputStream **out_log,
- GError **error) G_GNUC_UNUSED;
-
-static gboolean
-open_log (const char *name,
- GOutputStream **out_log,
- GError **error)
-{
- gboolean ret = FALSE;
- char *tmpdir = NULL;
- char *path = NULL;
- GFile *logf = NULL;
- GFileOutputStream *ret_log = NULL;
-
- path = g_strdup_printf ("%s/%s.log", tmpdir, name);
- logf = ot_gfile_new_for_path (path);
-
- ret_log = g_file_replace (logf, NULL, FALSE, 0, NULL, error);
- if (!ret_log)
- goto out;
-
- ret = TRUE;
- *out_log = (GOutputStream*)ret_log;
- ret_log = NULL;
- out:
- g_free (path);
- g_free (tmpdir);
- g_clear_object (&logf);
- g_clear_object (&ret_log);
- return ret;
-}
-
-gboolean
-osbuild_builtin_buildone (int argc, char **argv, const char *prefix, GError **error)
-{
- GOptionContext *context;
- gboolean ret = FALSE;
-
- context = g_option_context_new ("- Build current directory");
- g_option_context_add_main_entries (context, options, NULL);
-
- if (!g_option_context_parse (context, &argc, &argv, error))
- goto out;
-
- if (!raw && !repo_path)
- {
- ot_util_usage_error (context, "A result directory must be specified with --resultdir", error);
- goto out;
- }
-
- if (!generator)
- generator = g_build_filename (LIBEXECDIR, "ostree", "generators", "default", NULL);
-
-
-
- out:
- if (context)
- g_option_context_free (context);
- return ret;
-}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2011 Colin Walters <walters@verbum.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Colin Walters <walters@verbum.org>
- */
-
-#ifndef __OSBUILD_BUILTINS__
-#define __OSBUILD_BUILTINS__
-
-#include <glib-object.h>
-
-G_BEGIN_DECLS
-
-typedef enum {
- OSBUILD_BUILTIN_FLAG_NONE = 0,
-} OsbuildBuiltinFlags;
-
-typedef struct {
- const char *name;
- gboolean (*fn) (int argc, char **argv, const char *prefix, GError **error);
- int flags; /* OsbuildBuiltinFlags */
-} OsbuildBuiltin;
-
-gboolean osbuild_builtin_buildone (int argc, char **argv, const char *prefix, GError **error);
-
-G_END_DECLS
-
-#endif
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2011 Colin Walters <walters@verbum.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Colin Walters <walters@verbum.org>
- */
-
-#include "config.h"
-
-#include <gio/gio.h>
-
-#include "otutil.h"
-
-#include <string.h>
-#include <sys/wait.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-static const char *
-find_first_file (GFileTest test, const char *name, ...) G_GNUC_NULL_TERMINATED;
-
-static const char *
-find_first_file (GFileTest test, const char *name, ...)
-{
- va_list args;
-
- va_start (args, name);
-
- do
- {
- if (g_file_test (name, test))
- break;
- name = va_arg (args, const char *);
- }
- while (name != NULL);
-
- va_end (args);
-
- return name;
-}
-
-static void
-split_configure_make_args (int argc,
- char **argv,
- GPtrArray **out_configure_args,
- GPtrArray **out_make_args,
- GPtrArray **out_makeinstall_args)
-{
- int i;
-
- *out_configure_args = g_ptr_array_new ();
- *out_make_args = g_ptr_array_new ();
- *out_makeinstall_args = g_ptr_array_new ();
-
- for (i = 1; i < argc; i++)
- {
- if (g_str_has_prefix (argv[i], "--"))
- g_ptr_array_add (*out_configure_args, argv[i]);
- else if (g_str_has_prefix (argv[i], "DESTDIR="))
- g_ptr_array_add (*out_makeinstall_args, argv[i]);
- else
- g_ptr_array_add (*out_make_args, argv[i]);
- }
-}
-
-static void
-spawn_sync_or_fatal (char **args, char **env, GSpawnFlags flags)
-{
- GError *error = NULL;
- int estatus;
- char **iter;
-
- g_print ("osbuild: running: ");
- for (iter = args; *iter; iter++)
- g_print ("%s ", *iter);
- g_print ("\n");
- if (g_spawn_sync (NULL, args, env, flags, NULL, NULL, NULL, NULL, &estatus, &error))
- {
- if (WIFEXITED (estatus) && WEXITSTATUS (estatus) == 0)
- {
- g_message ("Subprocess %s exited successfully\n", args[0]);
- }
- else
- {
- if (WIFEXITED (estatus))
- g_error ("Subprocess %s exited with code %d\n", args[0], WEXITSTATUS (estatus));
- else if (WIFSIGNALED (estatus))
- g_error ("Subprocess %s killed by signal %d\n", args[0], WTERMSIG (estatus));
- else
- g_error ("Subprocess %s terminated with status %d\n", args[0], estatus);
- exit (1);
- }
- }
- else
- {
- g_error ("Failed to execute %s: %s\n", args[0], error->message);
- exit (1);
- }
-}
-
-static void
-ptr_array_extend (GPtrArray *dest, GPtrArray *to_append)
-{
- int i;
-
- for (i = 0; i < to_append->len; i++)
- g_ptr_array_add (dest, to_append->pdata[i]);
-}
-
-int
-main (int argc,
- char **argv)
-{
- GPtrArray *config_args;
- GPtrArray *make_args;
- GPtrArray *makeinstall_args;
- GPtrArray *args;
- char **subprocess_env;
-
- g_type_init ();
-
- g_set_prgname (argv[0]);
-
- args = g_ptr_array_new ();
-
- subprocess_env = g_get_environ ();
- ot_g_environ_setenv (subprocess_env, "LANG", "C", TRUE);
- ot_g_environ_unsetenv (subprocess_env, "LC_ALL");
-
- split_configure_make_args (argc, argv, &config_args, &make_args, &makeinstall_args);
-
- if (!g_file_test ("./configure", G_FILE_TEST_IS_EXECUTABLE))
- {
- const char *autogen;
- char **autogen_env;
-
- autogen = find_first_file (G_FILE_TEST_IS_EXECUTABLE, "./autogen", "./autogen.sh", NULL);
- if (!autogen)
- ot_util_fatal_literal ("No executable configure or autogen script found");
-
- autogen_env = g_strdupv (subprocess_env);
- ot_g_environ_setenv (autogen_env, "NOCONFIGURE", "1", TRUE);
-
- g_ptr_array_set_size (args, 0);
- g_ptr_array_add (args, (char*) autogen);
- g_ptr_array_add (args, NULL);
- spawn_sync_or_fatal ((char**)args->pdata, autogen_env, 0);
- }
-
- if (!g_file_test ("./configure", G_FILE_TEST_IS_EXECUTABLE))
- ot_util_fatal_literal ("autogen script failed to generate a configure script");
-
- g_ptr_array_set_size (args, 0);
- g_ptr_array_add (args, "./configure");
- ptr_array_extend (args, config_args);
- g_ptr_array_add (args, NULL);
- spawn_sync_or_fatal ((char**)args->pdata, subprocess_env, 0);
-
- g_ptr_array_set_size (args, 0);
- g_ptr_array_add (args, "make");
- ptr_array_extend (args, make_args);
- g_ptr_array_add (args, NULL);
- spawn_sync_or_fatal ((char**)args->pdata, subprocess_env, G_SPAWN_SEARCH_PATH);
-
- g_ptr_array_set_size (args, 0);
- g_ptr_array_add (args, "make");
- g_ptr_array_add (args, "install");
- ptr_array_extend (args, makeinstall_args);
- g_ptr_array_add (args, NULL);
- spawn_sync_or_fatal ((char**)args->pdata, subprocess_env, G_SPAWN_SEARCH_PATH);
-
- return 0;
-}
+++ /dev/null
-#!/usr/bin/python
-#
-# ostree-buildone:
-# Copyright 2010, 2011 Colin Walters <walters@verbum.org>
-# Licensed under the new-BSD license (http://www.opensource.org/licenses/bsd-license.php)
-
-# The build output is automatically logged to $TMPDIR/build-$(PWD).log.
-# For example, invoking metabuild in a directory named "foo" will log
-# to /tmp/build-foo.log
-#
-# You can pass arguments to metabuild; if they start with '--', they're
-# given to configure. Otherwise, they're passed to make.
-#
-# $ metabuild --enable-libfoo # passed to configure
-# $ metabuild -j 1 # passed to make
-
-import os,sys,subprocess,tempfile,re
-import select,time,stat,fcntl
-
-subprocess_nice_args = []
-
-# In the future we should test for this better; possibly implement a
-# custom fork handler
-try:
- chrt_args = ['chrt', '--idle', '0']
- proc = subprocess.Popen(chrt_args + ['true'])
- if proc.wait() == 0:
- subprocess_nice_args.extend(chrt_args)
-except OSError, e:
- pass
-
-try:
- ionice_args = ['ionice', '-c', '3', '-t']
- proc = subprocess.Popen(ionice_args + ['true'])
- if proc.wait() == 0:
- subprocess_nice_args.extend(ionice_args)
-except OSError, e:
- pass
-
-warning_re = re.compile(r'(: ((warning)|(error)|(fatal error)): )|(make(\[[0-9]+\])?: \*\*\*)')
-output_whitelist_re = re.compile(r'^(make(\[[0-9]+\])?: Entering directory)|(ostree-build )')
-
-_bold_sequence = None
-_normal_sequence = None
-if os.isatty(1):
- _bold_sequence = subprocess.Popen(['tput', 'bold'], stdout=subprocess.PIPE, stderr=open('/dev/null', 'w')).communicate()[0]
- _normal_sequence = subprocess.Popen(['tput', 'sgr0'], stdout=subprocess.PIPE, stderr=open('/dev/null', 'w')).communicate()[0]
-def _bold(text):
- if _bold_sequence is not None:
- return '%s%s%s' % (_bold_sequence, text, _normal_sequence)
- else:
- return text
-
-class Mainloop(object):
- DEFAULT = None
- def __init__(self):
- self._running = True
- self.poll = select.poll()
- self._timeouts = []
- self._pid_watches = {}
- self._fd_callbacks = {}
-
- @classmethod
- def get(cls, context):
- if context is None:
- if cls.DEFAULT is None:
- cls.DEFAULT = cls()
- return cls.DEFAULT
- raise NotImplementedError("Unknown context %r" % (context, ))
-
- def watch_fd(self, fd, callback):
- self.poll.register(fd)
- self._fd_callbacks[fd] = callback
-
- def unwatch_fd(self, fd):
- self.poll.unregister(fd)
- del self._fd_callbacks[fd]
-
- def watch_pid(self, pid, callback):
- self._pid_watches[pid] = callback
-
- def timeout_add(self, ms, callback):
- self._timeouts.append((ms, callback))
-
- def quit(self):
- self._running = False
-
- def run_once(self):
- min_timeout = None
- if len(self._pid_watches) > 0:
- min_timeout = 500
- for (ms, callback) in self._timeouts:
- if (min_timeout is None) or (ms < min_timeout):
- min_timeout = ms
- origtime = time.time() * 1000
- fds = self.poll.poll(min_timeout)
- for fd in fds:
- self._fd_callbacks[fd]()
- for pid in self._pid_watches:
- (opid, status) = os.waitpid(pid, os.WNOHANG)
- if opid != 0:
- self._pid_watches[pid](opid, status)
- del self._pid_watches[pid]
- newtime = time.time() * 1000
- diff = int(newtime - origtime)
- if diff < 0: diff = 0
- for i,(ms, callback) in enumerate(self._timeouts):
- remaining_ms = ms - diff
- if remaining_ms <= 0:
- callback()
- else:
- self._timeouts[i] = (remaining_ms, callback)
-
- def run(self):
- while self._running:
- self.run_once()
-
-class FileMonitor(object):
- def __init__(self):
- self._paths = {}
- self._path_modtimes = {}
- self._timeout = 1000
- self._timeout_installed = False
- self._loop = Mainloop.get(None)
-
- def _stat(self, path):
- try:
- st = os.stat(path)
- return st[stat.ST_MTIME]
- except OSError, e:
- return None
-
- def add(self, path, callback):
- if path not in self._paths:
- self._paths[path] = []
- self._path_modtimes[path] = self._stat(path)
- self._paths[path].append(callback)
- if not self._timeout_installed:
- self._timeout_installed = True
- self._loop.timeout_add(self._timeout, self._check_files)
-
- def _check_files(self):
- for (path,callbacks) in self._paths.iteritems():
- mtime = self._stat(path)
- orig_mtime = self._path_modtimes[path]
- if (mtime is not None) and (orig_mtime is None or (mtime > orig_mtime)):
- self._path_modtimes[path] = mtime
- for cb in callbacks:
- cb()
-
-_filemon = FileMonitor()
-
-class OutputFilter(object):
- def __init__(self, filename, output):
- self.filename = filename
- self.output = output
-
- # inherit globals
- self._warning_re = warning_re
- self._nonfilter_re = output_whitelist_re
-
- self._buf = ''
- self._warning_count = 0
- self._filtered_line_count = 0
- _filemon.add(filename, self._on_changed)
- self._fd = os.open(filename, os.O_RDONLY)
- fcntl.fcntl(self._fd, fcntl.F_SETFL, os.O_NONBLOCK)
-
- def _do_read(self):
- while True:
- buf = os.read(self._fd, 4096)
- if buf == '':
- break
- self._buf += buf
- self._flush()
-
- def _write_last_log_lines(self):
- _last_line_limit = 100
- f = open(logfile_path)
- lines = []
- for line in f:
- if line.startswith('ostree-build '):
- continue
- lines.append(line)
- if len(lines) > _last_line_limit:
- lines.pop(0)
- f.close()
- for line in lines:
- self.output.write('| ')
- self.output.write(line)
-
- def _flush(self):
- while True:
- p = self._buf.find('\n')
- if p < 0:
- break
- line = self._buf[0:p]
- self._buf = self._buf[p+1:]
- match = self._warning_re.search(line)
- if match:
- self._warning_count += 1
- self.output.write(line + '\n')
- else:
- match = self._nonfilter_re.search(line)
- if match:
- self.output.write(line + '\n')
- else:
- self._filtered_line_count += 1
-
- def _on_changed(self):
- self._do_read()
-
- def start(self):
- self._do_read()
-
- def finish(self, successful):
- self._do_read()
- if not successful:
- self._write_last_log_lines()
- pass
- self.output.write("ostree-build %s: %d warnings\n" % ('success' if successful else _bold('failed'),
- self._warning_count, ))
- self.output.write("ostree-build: full log path: %s\n" % (logfile_path, ))
-
- if successful:
- for f in os.listdir('_build'):
- path = os.path.join('_build', f)
- if f.startswith('artifact-'):
- self.output.write("ostree-build: created artifact: %s\n" % (f, ))
- sys.exit(0 if successful else 1)
-
-def _on_makeinstall_exit(pid, estatus):
- _output_filter.finish(estatus == 0)
-
-def _on_make_exit(pid, estatus):
- if estatus == 0:
- args = list(subprocess_nice_args)
- args.append('ostree-buildone-makeinstall-split-artifacts')
- _logfile_f.write("Running: %r\n" % (args, ))
- _logfile_f.flush()
- proc = subprocess.Popen(args, stdin=devnull, stdout=logfile_write_fd, stderr=logfile_write_fd)
- _loop.watch_pid(proc.pid, _on_makeinstall_exit)
- else:
- _output_filter.finish(False)
-
-def _get_version():
- if not os.path.isdir('.git'):
- sys.stderr.write("ostree-buildone: error: Couldn't find .git directory")
- sys.exit(1)
-
- proc = subprocess.Popen(['git', 'describe'], stdout=subprocess.PIPE)
- output = proc.communicate()[0].strip()
- if proc.wait() != 0:
- proc = subprocess.Popen(['git', 'rev-parse', 'HEAD'], stdout=subprocess.PIPE)
- if proc.wait() != 0:
- sys.stderr.write("ostree-buildone: error: git rev-parse HEAD failed")
- sys.exit(1)
- output = proc.communicate()[0].strip()
- return output
-
-if __name__ == '__main__':
- user_tmpdir = os.environ.get('XDG_RUNTIME_DIR')
- if user_tmpdir is None:
- user_tmpdir = os.path.join(os.environ.get('TMPDIR', '/tmp'), 'metabuild-%s' % (os.getuid(), ))
- else:
- user_tmpdir = os.path.join(user_tmpdir, 'ostree-build')
-
- os.environ['OSBUILD_VERSION'] = _get_version()
-
- if os.path.isdir('_build'):
- for filename in os.listdir('_build'):
- path = os.path.join('_build', filename)
- if filename.startswith('artifact-'):
- os.unlink(path)
-
- if not os.path.isdir(user_tmpdir):
- os.makedirs(user_tmpdir)
- logfile_path = os.path.join(user_tmpdir, '%s.log' % (os.path.basename(os.getcwd()), ))
- try:
- os.unlink(logfile_path)
- except OSError, e:
- pass
- logfile_write_fd = os.open(logfile_path, os.O_WRONLY | os.O_CREAT | os.O_EXCL)
- global _logfile_f
- _logfile_f = os.fdopen(logfile_write_fd, "w")
- sys.stdout.write('ostree-build: logging to %r\n' % (logfile_path, ))
- sys.stdout.flush()
-
- global _output_filter
- _output_filter = OutputFilter(logfile_path, sys.stdout)
- _output_filter.start()
-
- args = list(subprocess_nice_args)
- args.append('ostree-buildone-make')
- args.extend(sys.argv[1:])
- devnull=open('/dev/null')
- _logfile_f.write("Running: %r\n" % (args, ))
- _logfile_f.flush()
- proc = subprocess.Popen(args, stdin=devnull, stdout=logfile_write_fd, stderr=logfile_write_fd)
-
- global _loop
- _loop = Mainloop.get(None)
- _loop.watch_pid(proc.pid, _on_make_exit)
- _loop.run()
+++ /dev/null
-#!/usr/bin/python
-
-# ostree-buildone-raw: Generic build system wrapper
-# Copyright 2010, 2011 Colin Walters <walters@verbum.org>
-# Licensed under the new-BSD license (http://www.opensource.org/licenses/bsd-license.php)
-
-# ostree-buildone-raw wraps systems that implement the GNOME build API:
-# http://people.gnome.org/~walters/docs/build-api.txt
-
-import os,sys,subprocess,tempfile,re
-from multiprocessing import cpu_count
-import select,time
-
-root = None
-
-prefix = '/usr'
-
-# libdir detection
-if os.path.isdir('/lib64'):
- libdir=os.path.join(prefix, 'lib64')
-else:
- libdir=os.path.join(prefix, 'lib')
-
-default_buildapi_jobs = ['-j', '%d' % (cpu_count() * 2, )]
-configargs = ['--prefix=' + prefix,
- '--libdir=' + libdir,
- '--sysconfdir=/etc',
- '--localstatedir=/var',
- '--bindir=' + os.path.join(prefix, 'bin'),
- '--sbindir=' + os.path.join(prefix, 'sbin'),
- '--datadir=' + os.path.join(prefix, 'share'),
- '--includedir=' + os.path.join(prefix, 'include'),
- '--libexecdir=' + os.path.join(prefix, 'libexec'),
- '--mandir=' + os.path.join(prefix, 'share', 'man'),
- '--infodir=' + os.path.join(prefix, 'share', 'info')]
-makeargs = ['make']
-
-top_srcdir=os.getcwd()
-
-for arg in sys.argv[1:]:
- if arg.startswith('--'):
- configargs.append(arg)
- else:
- makeargs.append(arg)
-
-def log(msg):
- fullmsg = 'ostree-buildone: ' + msg + '\n'
- sys.stdout.write(fullmsg)
- sys.stdout.flush()
-
-def fatal(msg):
- log(msg)
- sys.exit(1)
-
-def run_sync(args, env=None):
- log("Running: %r" % (args, ))
- f = open('/dev/null', 'r')
- proc = subprocess.Popen(args, stdin=f, stdout=sys.stdout, stderr=sys.stderr,
- close_fds=True, env=env)
- f.close()
- returncode = proc.wait()
- log("pid %d exited with code %d" % (proc.pid, returncode))
- if returncode != 0:
- sys.exit(1)
-
-class BuildSystemScanner(object):
- @classmethod
- def _find_file(cls, names):
- for name in names:
- if os.path.exists(name):
- return name
- return None
-
- @classmethod
- def get_configure_source_script(cls):
- return cls._find_file(('./configure.ac', './configure.in'))
-
- @classmethod
- def get_configure_script(cls):
- return cls._find_file(('./configure', ))
-
- @classmethod
- def get_bootstrap_script(cls):
- return cls._find_file(('./autogen.sh', ))
-
- @classmethod
- def get_silent_rules(cls):
- src = cls.get_configure_source_script()
- if not src:
- return False
- f = open(src)
- for line in f:
- if line.find('AM_SILENT_RULES') >= 0:
- f.close()
- return True
- f.close()
- return False
-
-def _search_file(filename, pattern):
- f = open(filename)
- for line in f:
- if line.startswith(pattern):
- f.close()
- return line
- f.close()
- return None
-
-def _find_buildapi_makevariable(name):
- var = '.%s:' % (name, )
- line = None
- if os.path.exists('Makefile.in'):
- line = _search_file('Makefile.in', var)
- if not line and os.path.exists('Makefile'):
- line = _search_file('Makefile', var)
- return line is not None
-
-def phase_bootstrap():
- have_configure = BuildSystemScanner.get_configure_script()
- have_configure_source = BuildSystemScanner.get_configure_source_script()
- if not (have_configure or have_configure_source):
- fatal("No configure or bootstrap script detected; unknown buildsystem")
- return
-
- need_v1 = BuildSystemScanner.get_silent_rules()
- if need_v1:
- log("Detected AM_SILENT_RULES, adding --disable-silent-rules to configure")
- configargs.append('--disable-silent-rules')
-
- if have_configure:
- phase_configure()
- else:
- bootstrap = BuildSystemScanner.get_bootstrap_script()
- if bootstrap:
- log("Detected bootstrap script: %s, using it" % (bootstrap, ))
- args = [bootstrap]
- args.extend(configargs)
- # Add NOCONFIGURE; GNOME style scripts use this
- env = dict(os.environ)
- env['NOCONFIGURE'] = '1'
- run_sync(args, env=env)
- else:
- log("No bootstrap script found; using generic autoreconf")
- run_sync(['autoreconf', '-f', '-i'])
- phase_configure()
-
-def phase_configure():
- use_builddir = True
- doesnot_support_builddir = _find_buildapi_makevariable('buildapi-no-builddir')
- if doesnot_support_builddir:
- log("Found .buildapi-no-builddir; copying source tree to _build")
- shutil.rmtree('_build')
- os.mkdir('_build')
- shutil.copytree('.', '_build', symlinks=True,
- ignore=shutil.ignore_patterns('_build'))
- use_builddir = False
- builddir = '.'
- else:
- builddir = '_build'
-
- if not use_builddir:
- configdir = './'
- else:
- configdir = os.getcwd()
- builddir = builddir
- log("Using build directory %r" % (builddir, ))
- if not os.path.isdir(builddir):
- os.mkdir(builddir)
- os.chdir(builddir)
-
- configstatus = 'config.status'
- if not os.path.exists(configstatus):
- args = [os.path.join(configdir, 'configure')]
- args.extend(configargs)
- run_sync(args)
- else:
- log("Found %s, skipping configure" % (configstatus, ))
- phase_build()
-
-build_status = False
-
-def phase_build():
- if not os.path.exists('Makefile'):
- log("No Makefile found")
- sys.exit(1)
- args = makeargs
- user_specified_jobs = False
- for arg in args:
- if arg == '-j':
- user_specified_jobs = True
-
- if not user_specified_jobs:
- notparallel = _find_buildapi_makevariable('NOTPARALLEL')
- if not notparallel:
- log("Didn't find NOTPARALLEL, using parallel make by default")
- args.extend(default_buildapi_jobs)
-
- run_sync(args)
-
-def phase_complete():
- sys.exit(0)
-
-log("invocation arguments: %r" % (sys.argv, ))
-
-# Start off the process
-phase_bootstrap()
+++ /dev/null
-#!/usr/bin/python
-
-# ostree-buildone-raw: Generic build system wrapper
-# Copyright 2010, 2011 Colin Walters <walters@verbum.org>
-# Licensed under the new-BSD license (http://www.opensource.org/licenses/bsd-license.php)
-
-import os,sys,re,subprocess
-import tempfile,shutil
-
-_devel_regexps = map(re.compile,
- [r'/usr/include/',
- r'/usr/share/pkgconfig/',
- r'/.*lib(?:|(?:32)|(?:64))/pkgconfig/.*\.pc',
- r'/.*lib(?:|(?:32)|(?:64))/.*\.so$'])
-
-def log(msg):
- fullmsg = 'ostree-buildone: ' + msg + '\n'
- sys.stdout.write(fullmsg)
- sys.stdout.flush()
-
-tempfiles = []
-
-def do_exit(code):
- for tmpname in tempfiles:
- if os.path.isdir(tmpname):
- shutil.rmtree(tmpname)
- else:
- try:
- os.unlink(tmpname)
- pass
- except OSError, e:
- pass
- sys.exit(code)
-
-def fatal(msg):
- log(msg)
- do_exit(1)
-
-def run_sync(args, env=None):
- log("Running: %r" % (args, ))
- f = open('/dev/null', 'r')
- proc = subprocess.Popen(args, stdin=f, stdout=sys.stdout, stderr=sys.stderr,
- close_fds=True, env=env)
- f.close()
- returncode = proc.wait()
- if returncode == 0:
- func = log
- else:
- func = fatal
- func("pid %d exited with code %d" % (proc.pid, returncode))
-
-basename=os.path.basename(os.getcwd())
-artifact_prefix='artifact-%s,%s' % (basename, os.environ['OSBUILD_VERSION'])
-origdir=os.getcwd()
-os.chdir('_build')
-
-if not os.path.exists('Makefile'):
- log("No Makefile found")
- do_exit(1)
-
-(fd,fakeroot_temp)=tempfile.mkstemp(prefix='ostree-fakeroot-%s-' % (basename,))
-os.close(fd)
-tempfiles.append(fakeroot_temp)
-tempdir = tempfile.mkdtemp(prefix='ostree-build-%s-' % (basename,))
-tempfiles.append(tempdir)
-args = ['fakeroot', '-s', fakeroot_temp, 'make', 'install', 'DESTDIR=' + tempdir]
-run_sync(args)
-
-devel_files = set()
-runtime_files = set()
-
-oldpwd=os.getcwd()
-os.chdir(tempdir)
-for root, dirs, files in os.walk('.'):
- for filename in files:
- path = os.path.join(root, filename)
- matched = False
- for r in _devel_regexps:
- if r.match(path[1:]):
- devel_files.add(path)
- matched = True
- break
- if not matched:
- runtime_files.add(path)
-os.chdir(oldpwd)
-
-def make_artifact(name, from_files):
- artifact_target = '%s-%s.tar.gz' % (artifact_prefix, name)
- (fd,filelist_temp)=tempfile.mkstemp(prefix='ostree-filelist-%s-%s' % (basename, name))
- os.close(fd)
- tempfiles.append(filelist_temp)
- f = open(filelist_temp, 'w')
- for filename in from_files:
- f.write(filename)
- f.write('\n')
- f.close()
- args = ['fakeroot', '-i', fakeroot_temp, 'tar', '-c', '-z', '-C', tempdir, '-f', artifact_target, '-T', filelist_temp]
- run_sync(args)
-
-if devel_files:
- make_artifact('devel', devel_files)
-make_artifact('runtime', runtime_files)
-
-do_exit(0)
--- /dev/null
+#!/usr/bin/python
+
+import os,sys,re,subprocess
+
+chroot_path=sys.argv[1]
+
+proc_path=os.path.join(chroot_path, 'proc')
+subprocess.check_call(['mount', '-t', 'proc', 'proc', proc_path])
+
+subprocess.call(['chroot', chroot_path])
+
+subprocess.check_call(['umount', proc_path])
+
--- /dev/null
+#!/usr/bin/python
+#
+# Copyright 2011 Colin Walters <walters@verbum.org>
+# Licensed under the new-BSD license (http://www.opensource.org/licenses/bsd-license.php)
+
+import os,sys,subprocess,tempfile,re
+
+for
--- /dev/null
+#!/usr/bin/python
+#
+# Copyright 2010, 2011 Colin Walters <walters@verbum.org>
+# Licensed under the new-BSD license (http://www.opensource.org/licenses/bsd-license.php)
+
+# The build output is automatically logged to $TMPDIR/build-$(PWD).log.
+# For example, invoking metabuild in a directory named "foo" will log
+# to /tmp/build-foo.log
+
+import os,sys,subprocess,tempfile,re
+import select,time,stat,fcntl
+
+subprocess_nice_args = []
+
+# In the future we should test for this better; possibly implement a
+# custom fork handler
+try:
+ chrt_args = ['chrt', '--idle', '0']
+ proc = subprocess.Popen(chrt_args + ['true'])
+ if proc.wait() == 0:
+ subprocess_nice_args.extend(chrt_args)
+except OSError, e:
+ pass
+
+try:
+ ionice_args = ['ionice', '-c', '3', '-t']
+ proc = subprocess.Popen(ionice_args + ['true'])
+ if proc.wait() == 0:
+ subprocess_nice_args.extend(ionice_args)
+except OSError, e:
+ pass
+
+warning_re = re.compile(r'(: ((warning)|(error)|(fatal error)): )|(make(\[[0-9]+\])?: \*\*\*)')
+output_whitelist_re = re.compile(r'^(make(\[[0-9]+\])?: Entering directory)|(ostbuild )')
+
+_bold_sequence = None
+_normal_sequence = None
+if os.isatty(1):
+ _bold_sequence = subprocess.Popen(['tput', 'bold'], stdout=subprocess.PIPE, stderr=open('/dev/null', 'w')).communicate()[0]
+ _normal_sequence = subprocess.Popen(['tput', 'sgr0'], stdout=subprocess.PIPE, stderr=open('/dev/null', 'w')).communicate()[0]
+def _bold(text):
+ if _bold_sequence is not None:
+ return '%s%s%s' % (_bold_sequence, text, _normal_sequence)
+ else:
+ return text
+
+class Mainloop(object):
+ DEFAULT = None
+ def __init__(self):
+ self._running = True
+ self.poll = select.poll()
+ self._timeouts = []
+ self._pid_watches = {}
+ self._fd_callbacks = {}
+
+ @classmethod
+ def get(cls, context):
+ if context is None:
+ if cls.DEFAULT is None:
+ cls.DEFAULT = cls()
+ return cls.DEFAULT
+ raise NotImplementedError("Unknown context %r" % (context, ))
+
+ def watch_fd(self, fd, callback):
+ self.poll.register(fd)
+ self._fd_callbacks[fd] = callback
+
+ def unwatch_fd(self, fd):
+ self.poll.unregister(fd)
+ del self._fd_callbacks[fd]
+
+ def watch_pid(self, pid, callback):
+ self._pid_watches[pid] = callback
+
+ def timeout_add(self, ms, callback):
+ self._timeouts.append((ms, callback))
+
+ def quit(self):
+ self._running = False
+
+ def run_once(self):
+ min_timeout = None
+ if len(self._pid_watches) > 0:
+ min_timeout = 500
+ for (ms, callback) in self._timeouts:
+ if (min_timeout is None) or (ms < min_timeout):
+ min_timeout = ms
+ origtime = time.time() * 1000
+ fds = self.poll.poll(min_timeout)
+ for fd in fds:
+ self._fd_callbacks[fd]()
+ for pid in self._pid_watches:
+ (opid, status) = os.waitpid(pid, os.WNOHANG)
+ if opid != 0:
+ self._pid_watches[pid](opid, status)
+ del self._pid_watches[pid]
+ newtime = time.time() * 1000
+ diff = int(newtime - origtime)
+ if diff < 0: diff = 0
+ for i,(ms, callback) in enumerate(self._timeouts):
+ remaining_ms = ms - diff
+ if remaining_ms <= 0:
+ callback()
+ else:
+ self._timeouts[i] = (remaining_ms, callback)
+
+ def run(self):
+ while self._running:
+ self.run_once()
+
+class FileMonitor(object):
+ def __init__(self):
+ self._paths = {}
+ self._path_modtimes = {}
+ self._timeout = 1000
+ self._timeout_installed = False
+ self._loop = Mainloop.get(None)
+
+ def _stat(self, path):
+ try:
+ st = os.stat(path)
+ return st[stat.ST_MTIME]
+ except OSError, e:
+ return None
+
+ def add(self, path, callback):
+ if path not in self._paths:
+ self._paths[path] = []
+ self._path_modtimes[path] = self._stat(path)
+ self._paths[path].append(callback)
+ if not self._timeout_installed:
+ self._timeout_installed = True
+ self._loop.timeout_add(self._timeout, self._check_files)
+
+ def _check_files(self):
+ for (path,callbacks) in self._paths.iteritems():
+ mtime = self._stat(path)
+ orig_mtime = self._path_modtimes[path]
+ if (mtime is not None) and (orig_mtime is None or (mtime > orig_mtime)):
+ self._path_modtimes[path] = mtime
+ for cb in callbacks:
+ cb()
+
+_filemon = FileMonitor()
+
+class OutputFilter(object):
+ def __init__(self, filename, output):
+ self.filename = filename
+ self.output = output
+
+ # inherit globals
+ self._warning_re = warning_re
+ self._nonfilter_re = output_whitelist_re
+
+ self._buf = ''
+ self._warning_count = 0
+ self._filtered_line_count = 0
+ _filemon.add(filename, self._on_changed)
+ self._fd = os.open(filename, os.O_RDONLY)
+ fcntl.fcntl(self._fd, fcntl.F_SETFL, os.O_NONBLOCK)
+
+ def _do_read(self):
+ while True:
+ buf = os.read(self._fd, 4096)
+ if buf == '':
+ break
+ self._buf += buf
+ self._flush()
+
+ def _write_last_log_lines(self):
+ _last_line_limit = 100
+ f = open(logfile_path)
+ lines = []
+ for line in f:
+ if line.startswith('ostbuild '):
+ continue
+ lines.append(line)
+ if len(lines) > _last_line_limit:
+ lines.pop(0)
+ f.close()
+ for line in lines:
+ self.output.write('| ')
+ self.output.write(line)
+
+ def _flush(self):
+ while True:
+ p = self._buf.find('\n')
+ if p < 0:
+ break
+ line = self._buf[0:p]
+ self._buf = self._buf[p+1:]
+ match = self._warning_re.search(line)
+ if match:
+ self._warning_count += 1
+ self.output.write(line + '\n')
+ else:
+ match = self._nonfilter_re.search(line)
+ if match:
+ self.output.write(line + '\n')
+ else:
+ self._filtered_line_count += 1
+
+ def _on_changed(self):
+ self._do_read()
+
+ def start(self):
+ self._do_read()
+
+ def finish(self, successful):
+ self._do_read()
+ if not successful:
+ self._write_last_log_lines()
+ pass
+ self.output.write("ostbuild %s: %d warnings\n" % ('success' if successful else _bold('failed'),
+ self._warning_count, ))
+ self.output.write("ostbuild: full log path: %s\n" % (logfile_path, ))
+
+ if successful:
+ for f in os.listdir('_build'):
+ path = os.path.join('_build', f)
+ if f.startswith('artifact-'):
+ self.output.write("ostbuild: created artifact: %s\n" % (f, ))
+ sys.exit(0 if successful else 1)
+
+def _on_makeinstall_exit(pid, estatus):
+ _output_filter.finish(estatus == 0)
+
+def _on_make_exit(pid, estatus):
+ if estatus == 0:
+ args = list(subprocess_nice_args)
+ args.append('ostbuild-one-makeinstall-split-artifacts')
+ _logfile_f.write("Running: %r\n" % (args, ))
+ _logfile_f.flush()
+ proc = subprocess.Popen(args, stdin=devnull, stdout=logfile_write_fd, stderr=logfile_write_fd)
+ _loop.watch_pid(proc.pid, _on_makeinstall_exit)
+ else:
+ _output_filter.finish(False)
+
+def _get_version():
+ if not os.path.isdir('.git'):
+ sys.stderr.write("ostbuild-one: error: Couldn't find .git directory")
+ sys.exit(1)
+
+ proc = subprocess.Popen(['git', 'describe'], stdout=subprocess.PIPE)
+ output = proc.communicate()[0].strip()
+ if proc.wait() != 0:
+ proc = subprocess.Popen(['git', 'rev-parse', 'HEAD'], stdout=subprocess.PIPE)
+ if proc.wait() != 0:
+ sys.stderr.write("ostbuild-one: error: git rev-parse HEAD failed")
+ sys.exit(1)
+ output = proc.communicate()[0].strip()
+ return output
+
+if __name__ == '__main__':
+ user_tmpdir = os.environ.get('XDG_RUNTIME_DIR')
+ if user_tmpdir is None:
+ user_tmpdir = os.path.join(os.environ.get('TMPDIR', '/tmp'), 'metabuild-%s' % (os.getuid(), ))
+ else:
+ user_tmpdir = os.path.join(user_tmpdir, 'ostbuild')
+
+ os.environ['OSBUILD_VERSION'] = _get_version()
+
+ if os.path.isdir('_build'):
+ for filename in os.listdir('_build'):
+ path = os.path.join('_build', filename)
+ if filename.startswith('artifact-'):
+ os.unlink(path)
+
+ if not os.path.isdir(user_tmpdir):
+ os.makedirs(user_tmpdir)
+ logfile_path = os.path.join(user_tmpdir, '%s.log' % (os.path.basename(os.getcwd()), ))
+ try:
+ os.unlink(logfile_path)
+ except OSError, e:
+ pass
+ logfile_write_fd = os.open(logfile_path, os.O_WRONLY | os.O_CREAT | os.O_EXCL)
+ global _logfile_f
+ _logfile_f = os.fdopen(logfile_write_fd, "w")
+ sys.stdout.write('ostbuild: logging to %r\n' % (logfile_path, ))
+ sys.stdout.flush()
+
+ global _output_filter
+ _output_filter = OutputFilter(logfile_path, sys.stdout)
+ _output_filter.start()
+
+ args = list(subprocess_nice_args)
+ args.append('ostbuild-one-make')
+ args.extend(sys.argv[1:])
+ devnull=open('/dev/null')
+ _logfile_f.write("Running: %r\n" % (args, ))
+ _logfile_f.flush()
+ proc = subprocess.Popen(args, stdin=devnull, stdout=logfile_write_fd, stderr=logfile_write_fd)
+
+ global _loop
+ _loop = Mainloop.get(None)
+ _loop.watch_pid(proc.pid, _on_make_exit)
+ _loop.run()
--- /dev/null
+#!/usr/bin/python
+
+# ostree-buildone-raw: Generic build system wrapper
+# Copyright 2010, 2011 Colin Walters <walters@verbum.org>
+# Licensed under the new-BSD license (http://www.opensource.org/licenses/bsd-license.php)
+
+# ostree-buildone-raw wraps systems that implement the GNOME build API:
+# http://people.gnome.org/~walters/docs/build-api.txt
+
+import os,sys,subprocess,tempfile,re
+from multiprocessing import cpu_count
+import select,time
+
+root = None
+
+prefix = '/usr'
+
+# libdir detection
+if os.path.isdir('/lib64'):
+ libdir=os.path.join(prefix, 'lib64')
+else:
+ libdir=os.path.join(prefix, 'lib')
+
+default_buildapi_jobs = ['-j', '%d' % (cpu_count() * 2, )]
+configargs = ['--prefix=' + prefix,
+ '--libdir=' + libdir,
+ '--sysconfdir=/etc',
+ '--localstatedir=/var',
+ '--bindir=' + os.path.join(prefix, 'bin'),
+ '--sbindir=' + os.path.join(prefix, 'sbin'),
+ '--datadir=' + os.path.join(prefix, 'share'),
+ '--includedir=' + os.path.join(prefix, 'include'),
+ '--libexecdir=' + os.path.join(prefix, 'libexec'),
+ '--mandir=' + os.path.join(prefix, 'share', 'man'),
+ '--infodir=' + os.path.join(prefix, 'share', 'info')]
+makeargs = ['make']
+
+top_srcdir=os.getcwd()
+
+for arg in sys.argv[1:]:
+ if arg.startswith('--'):
+ configargs.append(arg)
+ else:
+ makeargs.append(arg)
+
+def log(msg):
+ fullmsg = 'ostree-buildone: ' + msg + '\n'
+ sys.stdout.write(fullmsg)
+ sys.stdout.flush()
+
+def fatal(msg):
+ log(msg)
+ sys.exit(1)
+
+def run_sync(args, env=None):
+ log("Running: %r" % (args, ))
+ f = open('/dev/null', 'r')
+ proc = subprocess.Popen(args, stdin=f, stdout=sys.stdout, stderr=sys.stderr,
+ close_fds=True, env=env)
+ f.close()
+ returncode = proc.wait()
+ log("pid %d exited with code %d" % (proc.pid, returncode))
+ if returncode != 0:
+ sys.exit(1)
+
+class BuildSystemScanner(object):
+ @classmethod
+ def _find_file(cls, names):
+ for name in names:
+ if os.path.exists(name):
+ return name
+ return None
+
+ @classmethod
+ def get_configure_source_script(cls):
+ return cls._find_file(('./configure.ac', './configure.in'))
+
+ @classmethod
+ def get_configure_script(cls):
+ return cls._find_file(('./configure', ))
+
+ @classmethod
+ def get_bootstrap_script(cls):
+ return cls._find_file(('./autogen.sh', ))
+
+ @classmethod
+ def get_silent_rules(cls):
+ src = cls.get_configure_source_script()
+ if not src:
+ return False
+ f = open(src)
+ for line in f:
+ if line.find('AM_SILENT_RULES') >= 0:
+ f.close()
+ return True
+ f.close()
+ return False
+
+def _search_file(filename, pattern):
+ f = open(filename)
+ for line in f:
+ if line.startswith(pattern):
+ f.close()
+ return line
+ f.close()
+ return None
+
+def _find_buildapi_makevariable(name):
+ var = '.%s:' % (name, )
+ line = None
+ if os.path.exists('Makefile.in'):
+ line = _search_file('Makefile.in', var)
+ if not line and os.path.exists('Makefile'):
+ line = _search_file('Makefile', var)
+ return line is not None
+
+def phase_bootstrap():
+ have_configure = BuildSystemScanner.get_configure_script()
+ have_configure_source = BuildSystemScanner.get_configure_source_script()
+ if not (have_configure or have_configure_source):
+ fatal("No configure or bootstrap script detected; unknown buildsystem")
+ return
+
+ need_v1 = BuildSystemScanner.get_silent_rules()
+ if need_v1:
+ log("Detected AM_SILENT_RULES, adding --disable-silent-rules to configure")
+ configargs.append('--disable-silent-rules')
+
+ if have_configure:
+ phase_configure()
+ else:
+ bootstrap = BuildSystemScanner.get_bootstrap_script()
+ if bootstrap:
+ log("Detected bootstrap script: %s, using it" % (bootstrap, ))
+ args = [bootstrap]
+ args.extend(configargs)
+ # Add NOCONFIGURE; GNOME style scripts use this
+ env = dict(os.environ)
+ env['NOCONFIGURE'] = '1'
+ run_sync(args, env=env)
+ else:
+ log("No bootstrap script found; using generic autoreconf")
+ run_sync(['autoreconf', '-f', '-i'])
+ phase_configure()
+
+def phase_configure():
+ use_builddir = True
+ doesnot_support_builddir = _find_buildapi_makevariable('buildapi-no-builddir')
+ if doesnot_support_builddir:
+ log("Found .buildapi-no-builddir; copying source tree to _build")
+ shutil.rmtree('_build')
+ os.mkdir('_build')
+ shutil.copytree('.', '_build', symlinks=True,
+ ignore=shutil.ignore_patterns('_build'))
+ use_builddir = False
+ builddir = '.'
+ else:
+ builddir = '_build'
+
+ if not use_builddir:
+ configdir = './'
+ else:
+ configdir = os.getcwd()
+ builddir = builddir
+ log("Using build directory %r" % (builddir, ))
+ if not os.path.isdir(builddir):
+ os.mkdir(builddir)
+ os.chdir(builddir)
+
+ configstatus = 'config.status'
+ if not os.path.exists(configstatus):
+ args = [os.path.join(configdir, 'configure')]
+ args.extend(configargs)
+ run_sync(args)
+ else:
+ log("Found %s, skipping configure" % (configstatus, ))
+ phase_build()
+
+build_status = False
+
+def phase_build():
+ if not os.path.exists('Makefile'):
+ log("No Makefile found")
+ sys.exit(1)
+ args = makeargs
+ user_specified_jobs = False
+ for arg in args:
+ if arg == '-j':
+ user_specified_jobs = True
+
+ if not user_specified_jobs:
+ notparallel = _find_buildapi_makevariable('NOTPARALLEL')
+ if not notparallel:
+ log("Didn't find NOTPARALLEL, using parallel make by default")
+ args.extend(default_buildapi_jobs)
+
+ run_sync(args)
+
+def phase_complete():
+ sys.exit(0)
+
+log("invocation arguments: %r" % (sys.argv, ))
+
+# Start off the process
+phase_bootstrap()
--- /dev/null
+#!/usr/bin/python
+
+# ostree-buildone-raw: Generic build system wrapper
+# Copyright 2010, 2011 Colin Walters <walters@verbum.org>
+# Licensed under the new-BSD license (http://www.opensource.org/licenses/bsd-license.php)
+
+import os,sys,re,subprocess
+import tempfile,shutil
+
+_devel_regexps = map(re.compile,
+ [r'/usr/include/',
+ r'/usr/share/pkgconfig/',
+ r'/.*lib(?:|(?:32)|(?:64))/pkgconfig/.*\.pc',
+ r'/.*lib(?:|(?:32)|(?:64))/.*\.so$'])
+
+def log(msg):
+ fullmsg = 'ostree-buildone: ' + msg + '\n'
+ sys.stdout.write(fullmsg)
+ sys.stdout.flush()
+
+tempfiles = []
+
+def do_exit(code):
+ for tmpname in tempfiles:
+ if os.path.isdir(tmpname):
+ shutil.rmtree(tmpname)
+ else:
+ try:
+ os.unlink(tmpname)
+ pass
+ except OSError, e:
+ pass
+ sys.exit(code)
+
+def fatal(msg):
+ log(msg)
+ do_exit(1)
+
+def run_sync(args, env=None):
+ log("Running: %r" % (args, ))
+ f = open('/dev/null', 'r')
+ proc = subprocess.Popen(args, stdin=f, stdout=sys.stdout, stderr=sys.stderr,
+ close_fds=True, env=env)
+ f.close()
+ returncode = proc.wait()
+ if returncode == 0:
+ func = log
+ else:
+ func = fatal
+ func("pid %d exited with code %d" % (proc.pid, returncode))
+
+basename=os.path.basename(os.getcwd())
+artifact_prefix='artifact-%s,%s' % (basename, os.environ['OSBUILD_VERSION'])
+origdir=os.getcwd()
+os.chdir('_build')
+
+if not os.path.exists('Makefile'):
+ log("No Makefile found")
+ do_exit(1)
+
+(fd,fakeroot_temp)=tempfile.mkstemp(prefix='ostree-fakeroot-%s-' % (basename,))
+os.close(fd)
+tempfiles.append(fakeroot_temp)
+tempdir = tempfile.mkdtemp(prefix='ostree-build-%s-' % (basename,))
+tempfiles.append(tempdir)
+args = ['fakeroot', '-s', fakeroot_temp, 'make', 'install', 'DESTDIR=' + tempdir]
+run_sync(args)
+
+devel_files = set()
+runtime_files = set()
+
+oldpwd=os.getcwd()
+os.chdir(tempdir)
+for root, dirs, files in os.walk('.'):
+ for filename in files:
+ path = os.path.join(root, filename)
+ matched = False
+ for r in _devel_regexps:
+ if r.match(path[1:]):
+ devel_files.add(path)
+ matched = True
+ break
+ if not matched:
+ runtime_files.add(path)
+os.chdir(oldpwd)
+
+def make_artifact(name, from_files):
+ artifact_target = '%s-%s.tar.gz' % (artifact_prefix, name)
+ (fd,filelist_temp)=tempfile.mkstemp(prefix='ostree-filelist-%s-%s' % (basename, name))
+ os.close(fd)
+ tempfiles.append(filelist_temp)
+ f = open(filelist_temp, 'w')
+ for filename in from_files:
+ assert ('\n' not in filename)
+ f.write(filename)
+ f.write('\n')
+ f.close()
+ args = ['fakeroot', '-i', fakeroot_temp, 'tar', '-c', '-z', '-C', tempdir, '-f', artifact_target, '-T', filelist_temp]
+ run_sync(args)
+
+if devel_files:
+ make_artifact('devel', devel_files)
+make_artifact('runtime', runtime_files)
+
+do_exit(0)